﻿using System;

namespace Community.CsharpSqlite.Entity
{
    /*
     ** Internally, the vdbe manipulates nearly all SQL values as Mem
     ** structures. Each Mem struct may cache multiple representations (string,
     ** integer etc.) of the same value.  A value (and therefore Mem structure)
     ** has the following properties:
     **
     ** Each value has a manifest type. The manifest type of the value stored
     ** in a Mem struct is returned by the MemType(Mem*) macro. The type is
     ** one of FundamentalDataType.SQLITE_NULL, FundamentalDataType.SQLITE_INTEGER, SQLITE_REAL, FundamentalDataType.SQLITE_TEXT or
     ** FundamentalDataType.SQLITE_BLOB.
     */

    public class Mem
    {
        public struct union_ip
        {
#if DEBUG_CLASS_MEM || DEBUG_CLASS_ALL
public long _i;              /* First operand */
public long i
{
get { return _i; }
set { _i = value; }
}
#else
            public long i; /* Integer value. */
#endif
            public int nZero; /* Used when bit MEMTermFlag.MEM_Zero is set in flags */
            public FuncDef pDef; /* Used only when flags==MEMTermFlag.MEM_Agg */
            public RowSet pRowSet; /* Used only when flags==MEMFlag.MEM_RowSet */
            public VdbeFrame pFrame; /* Used when flags==MEMFlag.MEM_Frame */
        };

        public union_ip u;
        public double r; /* Real value */
        public sqlite3 db; /* The associated database connection */
        public string z; /* String value */
        public byte[] zBLOB; /* BLOB value */
        public int n; /* Number of characters in string value, excluding '\0' */
#if DEBUG_CLASS_MEM || DEBUG_CLASS_ALL
public ushort _flags;              /* First operand */
public ushort flags
{
get { return _flags; }
set { _flags = value; }
}
#else
        public ushort flags = MEMFlag.MEM_Null; /* Some combination of MEMFlag.MEM_Null, MEMFlag.MEM_Str, MEMTermFlag.MEM_Dyn, etc. */
#endif
        public byte type = FundamentalDataType.SQLITE_NULL; /* One of FundamentalDataType.SQLITE_NULL, FundamentalDataType.SQLITE_TEXT, FundamentalDataType.SQLITE_INTEGER, etc */
        public byte enc; /* Const.SQLITE_UTF8, Const.SQLITE_UTF16BE, Const.SQLITE_UTF16LE */
        public dxDel xDel; /* If not null, call this function to delete Mem.z */
        // Not used under c#
        //public string zMalloc;      /* Dynamic buffer allocated by Malloc.sqlite3Malloc() */
        public Mem _Mem; /* Used when C# overload Z as MEM space */
        public SumCtx _SumCtx; /* Used when C# overload Z as Sum context */
        public SubProgram[] _SubProgram; /* Used when C# overload Z as SubProgram*/
        public StrAccum _StrAccum; /* Used when C# overload Z as STR context */
        public object _MD5Context; /* Used when C# overload Z as MD5 context */


        public void CopyTo(Mem ct)
        {
            ct.u = u;
            ct.r = r;
            ct.db = db;
            ct.z = z;
            if (zBLOB == null) ct.zBLOB = null;
            else
            {
                ct.zBLOB = Malloc.sqlite3Malloc(zBLOB.Length);
                Buffer.BlockCopy(zBLOB, 0, ct.zBLOB, 0, zBLOB.Length);
            }
            ct.n = n;
            ct.flags = flags;
            ct.type = type;
            ct.enc = enc;
            ct.xDel = xDel;
        }
    };
}